﻿/*--------------------------------------------------------------------------------------------------------------------------------

 Copyright © Microsoft Corporation.  All Rights Reserved.
 This code released under the terms of the 
 Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

 This "labelc2rdrive" program is used to label the Office Click-to-Run 2010 virtual drive letter after the OS OOBE.
 An easy way to start it is to create a "SetupComplete.cmd" script place in c:\windows\setup\scripts\ to launch it.
 A sample SetupComplete.cmd script is included in this project and copied to the output directory.
 
 Supported OS versions: Windows Vista SP1 and later, Windows 7 RTM and later
 This program needs to be executed with elevated rights and will elevate if necessary.

 This code needs to be compiled with the "Any Cpu" option in order to function proper.

 Functionality:
 1. The program detects the preferred OS UI language using the CultureInfo class
 2. The found OS UI language gets queried against the application configuration file which maps it to the right drive label.
 3. The label gets applied to the drive by creating the necessary registry keys. It handles the special case for Windows Vista 
    64 bit as well.
 4. All settings (c2r drive letter, UI languages, fallback label and matching labels) are stored in the app.config file.

 Version 1.0 by svengru - 04/16/2010

--------------------------------------------------------------------------------------------------------------------------------*/


using System;
using System.Configuration;
using System.Globalization;
using Microsoft.Win32;

namespace labelc2rdrive
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Preferred UI language is {0}.", CultureInfo.CurrentUICulture.Name);

            try
            {
                string s_c2rdriveletter = System.Configuration.ConfigurationManager.AppSettings["c2rdriveletter"]; //s_c2rdriveletter: CR2 drive letter from app.config
                if (s_c2rdriveletter != null)
                    Console.WriteLine("The C2R drive letter is {0}.", s_c2rdriveletter);
                else throw new ConfigurationErrorsException("No drive letter specified.");

                string s_registryvalue = System.Configuration.ConfigurationManager.AppSettings[CultureInfo.CurrentUICulture.Name]; //s_registryvalue: c2r drive label from app.config 
                if (s_registryvalue != null)
                    Console.WriteLine("Matching label found.");
                else
                {
                    Console.WriteLine("No label for {0} found.", CultureInfo.CurrentUICulture.Name);
                    s_registryvalue = System.Configuration.ConfigurationManager.AppSettings["fallbacklabel"];
                    if (s_registryvalue != null)
                        Console.WriteLine("The default label will be used: {0}", s_registryvalue);
                    else throw new ConfigurationErrorsException("No default label found in the .config file");
                }

                try
                {
                    // Writing the registry key to the none WOW64 enviroment. This is sufficient for Win7 as the key is shared, but Win Vista needs an extra key in the Wow6432Node.
                    RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\" + s_c2rdriveletter + "\\DefaultLabel");
                    if (key == null)
                    {
                        Console.WriteLine("The registry key does not exist. Writing it.");

                        key = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\" + s_c2rdriveletter + "\\DefaultLabel");
                        key.SetValue(null, s_registryvalue);
                        key.Close();
                    }
                    else Console.WriteLine("The registry key does already exist.");

                    //Detect Windows Vista x64 and set the additonal key in the Wow6432Node
                    //Details on the changes are here: http://msdn.microsoft.com/en-us/library/aa384253(v=VS.85).aspx

                    //Let's detect Windows Vista first
                    OperatingSystem os = Environment.OSVersion;
                    Version os_vs = os.Version;
                    if ((os.Platform == PlatformID.Win32NT) && (os_vs.Major == 6) && (os_vs.Minor == 0))
                    {
                        //There is currently no managed API that can return the OS architecture. Looking for the Wow6432Node is one way.
                        RegistryKey wow6432_key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node");
                        if (wow6432_key != null)
                        {
                            wow6432_key.Close();
                            Console.WriteLine("Windows Vista 64bit detected.");

                            RegistryKey vista_wow64_key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\" + s_c2rdriveletter + "\\DefaultLabel");

                            if (vista_wow64_key == null)
                            {
                                Console.WriteLine("Registry key in Vista WOW6432Node does not exist. Writing it.");

                                vista_wow64_key = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\" + s_c2rdriveletter + "\\DefaultLabel");
                                vista_wow64_key.SetValue(null, s_registryvalue);
                                vista_wow64_key.Close();
                            }
                            else Console.WriteLine("The registry key does already exist.");
                        }
                    }

                }
                catch (Exception e)
                {
                    Console.WriteLine("ERROR!! Issue accessing the registry: {0}", e.ToString());
                }

            }
            catch (ConfigurationErrorsException e)
            {
                Console.WriteLine("ERROR!! There is an issue with the .config file: {0}", e.ToString());
            }

            //for debugging only
            //Console.ReadLine();

        }
   }
}
